package cn.hsa.fqz.common.utils;

import cn.hsa.hsaf.core.framework.util.PageResult;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class EntityCopyUtil<T, R> {

    /**
     * 单体复制
     */
    public static <T> T copy(Object source, Class<T> clazz) {
        if (source == null) {
            return null;
        }
        T obj = null;
        try {
            obj = clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        BeanUtils.copyProperties(source, obj);
        return obj;
    }

    /**
     * 扩展单体复制 包括对象内部List复制
     */
    final static List<String> suffixs = Arrays.asList("DTO", "BO", "VO", "DO", "PO");

    public static <T, R> T copy(Object source, Class<T> tClass, Class<R>... rClasses) {
        if (source == null) {
            return null;
        }
        try {
            int index = 0;
            T target = tClass.newInstance();
            BeanUtils.copyProperties(source, target);
            for (Field sourceField : source.getClass().getDeclaredFields()) {
                if (List.class.isAssignableFrom(sourceField.getType())) {
                    Field targetField = target.getClass().getDeclaredField(sourceField.getName());
                    Method targetSetMethod = target.getClass().getMethod("set".concat(upperFirstStr(targetField.getName())),
                            List.class);
                    Method sourceGetMethod = source.getClass().getMethod("get".concat(upperFirstStr(targetField.getName())),
                            null);
                    List sourceList = (List) sourceGetMethod.invoke(source, null);
                    List<R> list = copyList(sourceList, rClasses[index]);
                    targetSetMethod.invoke(target, list);
                    index ++;
                }
            }
            return target;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    private static String upperFirstStr(String filedName) {
        char c = Character.toUpperCase(filedName.charAt(0));
        char[] chars = filedName.toCharArray();
        chars[0] = c;
        return new String(chars);
    }

    /**
     * 列表复制
     */
    public static <T> List<T> copyList(List source, Class<T> clazz) {
        List<T> target = new ArrayList<>();
        if (!CollectionUtils.isEmpty(source)) {
            for (Object c : source) {
                T obj = copy(c, clazz);
                target.add(obj);
            }
        }
        return target;
    }

    /**
     * 分页复制
     */
    public static <T, R> PageResult<T> copyPage(PageResult<R> source, Class<T> clazz) {
        PageResult<T> result = EntityCopyUtil.copy(source, PageResult.class);
        if (!CollectionUtils.isEmpty(source.getData())) {
            result.setData(copyList(source.getData(), clazz));
        }
        return result;
    }

    /**
     * 分页复制
     */
    public static <T, R, M> PageResult<T> copyPage(PageResult<R> source, Class<T> clazz, Class<M> mClass) {
        PageResult<T> result = EntityCopyUtil.copy(source, PageResult.class);
        List<T> target = new ArrayList<>();
        if (!CollectionUtils.isEmpty(source.getData())) {
            for (Object c : source.getData()) {
                T obj = copy(c, clazz, mClass);
                target.add(obj);
            }
        }
        result.setData(target);
        return result;
    }

}
